#pragma once

#define PER_CPU_SHARED_ALIGNED_SECTION ""

#ifndef PER_CPU_BASE_SECTION
#ifdef CONFIG_SMP
#define PER_CPU_BASE_SECTION ".data..percpu"
#else
#define PER_CPU_BASE_SECTION ".data"
#endif
#endif

#ifndef PER_CPU_ATTRIBUTES
#define PER_CPU_ATTRIBUTES
#endif

#define __PCPU_ATTRS(sec)                                       \
    __percpu __attribute__((section(PER_CPU_BASE_SECTION sec))) \
    PER_CPU_ATTRIBUTES

#define DEFINE_PER_CPU_SECTION(type, name, sec) \
    __PCPU_ATTRS(sec)                           \
    __typeof__(type) name

#define DEFINE_PER_CPU(type, name) \
    DEFINE_PER_CPU_SECTION(type, name, "")

#define PERCPU_PTR(__p) \
    (__typeof__(*(__p)) *)((__p))

#define DECLARE_PER_CPU_SECTION(type, name, sec) \
    extern __PCPU_ATTRS(sec) __typeof__(type) name

#define DECLARE_PER_CPU(type, name) \
    DECLARE_PER_CPU_SECTION(type, name, ".data..percpu")

#define DEFINE_PER_CPU_READ_MOSTLY(type, name) \
    DEFINE_PER_CPU_SECTION(type, name, "..read_mostly")

#define DEFINE_PER_CPU_ALIGNED(type, name) \
    DEFINE_PER_CPU_SECTION(type, name, PER_CPU_SHARED_ALIGNED_SECTION) \
    ____cacheline_aligned

#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \
    DEFINE_PER_CPU_SECTION(type, name, "") \
    ____cacheline_aligned

#ifdef CONFIG_SMP
#include <linux/smp/percpu-defs-mp.h>
#else
#include <linux/smp/percpu-defs-up.h>
#endif

#define __this_cpu_write(pcp, val)
